#ifndef __UDSF_SPI_C_
#define __UDSF_SPI_C_

#include "udf_global.h"

/*
*   notice:
*   UDSF 同UDF编程：不可调用cstd-lib,只可调用"sdk_ifs_udk_cfg.h"、"sys_api.h"中列出的API函数。
*   UDSF文件内函数均需使用static修饰符，且UDF中以#include "UDSF.c"形式引用
*/

static void udsf_spi_init(void) __attribute__((unused));
static void udsf_spi_send_string(char* pStr) __attribute__((unused));
static void udsf_spi_send_data(uint8_t* pData,int data_len) __attribute__((unused));
static void udsf_spi_send_data_trans(uint8_t* pData,int data_len) __attribute__((unused));
static void udsf_spi_send_data_base16(uint8_t* pData,int data_len) __attribute__((unused));
static void udsf_spi_send_u32_base16(int endian,uint32_t* Data,int data_len,char* start,char*end) __attribute__((unused));
static void udsf_spi_send_u16_base16(int endian,uint16_t* Data,int data_len,char* start,char*end) __attribute__((unused));
static void udsf_spi_send_u8_base16(uint8_t* Data,int data_len,char* start,char*end) __attribute__((unused));


/*endian: 0 -> little-endian 1-> big-enndian*/
static void udsf_spi_send_u32_base16(int endian,uint32_t* Data,int data_len,char* start,char*end){

	uint8_t data[4];
	if( start ){
		udsf_spi_send_string(start);
	}
	for ( int i = 0;i<data_len;i++){
		if( endian == 0 ){
			*((uint32_t*)(&data)) = Data[i];
		}else{
			data[0] = Data[i]>>24;
			data[1] = Data[i]>>16;
			data[2] = Data[i]>>8;
			data[3] = Data[i];
		}
		udsf_spi_send_data_base16(data,sizeof(data));
	}
	if( end ){
		udsf_spi_send_string(end);
	}
}

/*endian: 0 -> little-endian 1-> big-enndian*/
static void udsf_spi_send_u16_base16(int endian,uint16_t* Data,int data_len,char* start,char*end){

	uint8_t data[2];
	if( start ){
		udsf_spi_send_string(start);
	}
	for ( int i = 0;i<data_len;i++){
		if( endian == 0 ){
			*((uint16_t*)(&data)) = Data[i];
		}else{
			data[0] = Data[i]>>8;
			data[1] = Data[i];
		}
		udsf_spi_send_data_base16(data,sizeof(data));
	}
	if( end ){
		udsf_spi_send_string(end);
	}
}

/*endian: 0 -> little-endian 1-> big-enndian*/
static void udsf_spi_send_u8_base16(uint8_t* Data,int data_len,char* start,char*end){

	if( start ){
		udsf_spi_send_string(start);
	}

	udsf_spi_send_data_base16(Data,data_len);

	if( end ){
		udsf_spi_send_string(end);
	}
}

static void udsf_spi_send_string(char* pStr){
	
	GPIO0_4 = 0;
	USCI0->TRX = 0x00;  // delay	
	
	for( int i=0;;i++ ){
		if( pStr[i] == '\0' ){
			break;
		}
		USCI0->TRX = pStr[i];
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
	}
	
	GPIO0_4 = 1;
}

static void udsf_spi_init(void){
	Write_M32(0x50010000,paramFunc->gpio_pmode|GPIO_PIN_4);//GPIO0.4 Output
	GPIO0_4=1;	
	Write_M32(0x4001C018,(paramFunc->gpio_pmux0&0xffff000f)|0x1110);//PINMUX->MUX0 add usci0
	SYSC->SWRST &=~USCI0_SWRST_N_Msk;
	SYSC->SWRST |= USCI0_SWRST_N_Msk;
	USCI0->CFG0 = 0;        // wk_mode=spi
	USCI0->CFG1 =   0<<20 | // slv cs gpio
									0<<19 | // slv cs lvl
									0<<18 | // master
									0<<17 | // idle sck low
									1<<16 | // negedge change, posedge sample
									0<<12 | // no inv
									0<<10 | // stop bit
									0<< 9 | // par_off
									0<< 8 | // par_typ
									1<< 6 | // msb
									1<< 4 | // 8-bit
									0<< 2 | // no half-duplex
									1<< 1 | // rx_en
									1<< 0 ; // tx_en
		USCI0->BAUD = 0;
		USCI0->MOD  = 0;
		USCI0->CLK_DIV = 0;	
}


static void udsf_spi_send_data(uint8_t* pData,int data_len){
	GPIO0_4=0;
	USCI0->TRX = 0x00;  // delay	
	for( int i=0;i<data_len;i++ ){
		USCI0->TRX = pData[i];
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0); //USCI0 ISR
	}
	GPIO0_4=1;	
}


/*send data and 0xff->0xfd 0x02 0xfe->0xfd 0x01 0xfd->0xfd 0x00 */
static void udsf_spi_send_data_trans(uint8_t*pData,int data_len){	
	
	uint8_t data;

	GPIO0_4 = 0;
	USCI0->TRX = 0x00;  // delay	
	for( int i=0;i<data_len;i++ ){
		if( pData[i] > 0xfc ){
			USCI0->TRX = 0xfd;
			data = pData[i] - 0xfd;
			while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
			USCI0->TRX = data;
		}
		else{
			USCI0->TRX = pData[i];
		}
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
	}
	GPIO0_4 = 1;
}


static void udsf_spi_send_data_base16(uint8_t* pData,int data_len){

	uint8_t tmp_dataA,tmp_dataB,tmp_out;

	GPIO0_4 = 0;
	USCI0->TRX = 0x00;  // delay	
	for( int i=0;i<data_len;i++ ){
		tmp_dataA = (pData[i]&0xf0)>>4;
		if( tmp_dataA > 9 ){
			tmp_out = 'A'+(tmp_dataA-10);
		}else{
			tmp_out = '0'+tmp_dataA;
		}
		USCI0->TRX = tmp_out;  // send high-4-bit
		
		tmp_dataB = (pData[i]&0x0f);
		if( tmp_dataB > 9 ){
			tmp_out = 'A'+(tmp_dataB-10);
		}else{
			tmp_out = '0'+tmp_dataB;
		}
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
		USCI0->TRX = tmp_out;  // send low-4-bit
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
		USCI0->TRX = ' ';      // send space
		while((Read_M32(0x40000014)&USCI_ISR_TXE_Msk)==0);
	}
	GPIO0_4 = 1;
}
#endif
